package crud.dao.impl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import common.utils.BeanUtil;
import common.utils.FileTool;

import crud.client.annotation.Parameter;
import crud.client.data.DependenceToOne;
import crud.client.data.Table;
import crud.client.dialog.factory.WindowFactory;
import crud.client.factory.validator.field.ValidatorFactory;
import crud.client.factory.validator.table.TableValidatorFactory;
import crud.dao.TableDAO;

public class TableDAOImpl implements TableDAO
{
	public List<Table> loadAll()
	{
		// La liste des tables
		List<Table> tableList = new ArrayList<Table>();
		Document fileContent = FileTool.fileAsURLToXMLDocument("ressource/ReferenceTable.xml");
		for (int cp = 0; cp <= fileContent.getFirstChild().getChildNodes().getLength() - 1; cp++)
		{
			Node node = fileContent.getFirstChild().getChildNodes().item(cp);
			if (node.getNodeName().equals("Table"))
			{
				Table table = new Table();
				tableList.add(table);
				BeanUtil.populate(table, node);
				table.setWindowFactory((WindowFactory) BeanUtil.newInstance(table.getWindowFactoryClassName()));
			}
		}
		
		// Génération de la liste des dépendances
		Map<String, List<DependenceToOne>> dependanceMap = new HashMap<String, List<DependenceToOne>>();
		for (Table table : tableList)
		{
			Class<?> entityClass = BeanUtil.forName(table.getMappingClassName());
			List<Field> toOneFieldList = BeanUtil.getToOneFields(entityClass);
			for (Field field : toOneFieldList)
			{
				String toOneClassName = field.getType().getName();
				 List<DependenceToOne> dependenceList = dependanceMap.get(toOneClassName);
				 
				 if (dependenceList == null)
				 {
					 dependenceList = new ArrayList<DependenceToOne>();
					 dependanceMap.put(toOneClassName, dependenceList);
				 }
				 dependenceList.add(new DependenceToOne(table.getMappingClassName(), field.getName()));
			}
		}
		
		// Renseignement de la liste des dépendances avec la la map générée
		for (Table table : tableList)
		{
			if (dependanceMap.containsKey(table.getMappingClassName()) == true)
			{
				table.setDependingEntities(dependanceMap.get(table.getMappingClassName()));
			}
		}
		
		return tableList;
	}
}
